﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace SpriteMaker
{
    public partial class ModulWorkingPanel : Control
    {
        //private Image texture;
        private int xImage, yImage;
        private float zoom = 1.0f;
        private int lastMouseX, lastMouseY;
        private float moduleOriginalX, moduleOriginalY;
        private Module activeModule;
        public formMain formInstance;
        private int delta = 2;
        private enum MouseModuleState
        {
            None,
            Drag,
            ResizeLeft,
            ResizeRight,
            ResizeTop,
            ResizeBottom,
            ResizeLeftTop,
            ResizeLeftBottom,
            ResizeRightTop,
            ResizeRightBottom,
        }
        private MouseModuleState mouseState = MouseModuleState.None;
        public ModulWorkingPanel()
        {
            InitializeComponent();
            this.DoubleBuffered = true;
            this.MouseWheel += ModulWorkingPanel_MouseWheel;
        }

        void ModulWorkingPanel_MouseWheel(object sender, MouseEventArgs e)
        {
            int numberOfTextLinesToMove = e.Delta / 120;
            zoom += numberOfTextLinesToMove * 0.5f;
            if (zoom < 0.5f)
            {
                zoom = 0.5f;
            }
            this.Refresh();
        }

        protected override void OnPaint(PaintEventArgs pe)
        {
            base.OnPaint(pe);
            pe.Graphics.Clear(Color.Gray);
            System.Drawing.Drawing2D.GraphicsContainer container = pe.Graphics.BeginContainer();
            pe.Graphics.TranslateTransform(xImage, yImage);
            pe.Graphics.ScaleTransform(zoom, zoom);
            if (formInstance.GetImage() != null)
            {
                pe.Graphics.DrawImage(formInstance.GetImage(), new Rectangle(0, 0, formInstance.GetImage().Width, formInstance.GetImage().Height));
            }
            if (activeModule != null)
            {
                Pen pen = new Pen(Color.FromArgb(150,255,0,0));
                pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
                pe.Graphics.DrawRectangle(pen, activeModule.x, activeModule.y, activeModule.width, activeModule.height);
            }
            pe.Graphics.EndContainer(container);
        }
        /*
        public void SetImage(Image im)
        {
            texture = im;
            this.Refresh();
        }
        */
        private void ModulWorkingPanel_Click(object sender, EventArgs e)
        {

        }

        private void ModulWorkingPanel_MouseClick(object sender, MouseEventArgs e)
        {
            int x = (int)((e.X - xImage) / zoom);
            int y = (int)((e.Y - yImage) / zoom);
            if (e.Button == System.Windows.Forms.MouseButtons.Right)
            {
                contextMenuModulWorkingPanel.Show(this, e.X,e.Y);
            }
            else if(e.Button == System.Windows.Forms.MouseButtons.Left)
            {
                if (activeModule == null || Util.PointInRect(x, y, activeModule.x, activeModule.y
                    , activeModule.width, activeModule.height) == false)
                {
                    //search module
                    for (int i = 0; i < Sprite.spriteInstance.moduleList.Count; i++)
                    {
                        if (Util.PointInRect(x, y, Sprite.spriteInstance.moduleList[i].x, Sprite.spriteInstance.moduleList[i].y
                            , Sprite.spriteInstance.moduleList[i].width, Sprite.spriteInstance.moduleList[i].height))
                        {
                            activeModule = Sprite.spriteInstance.moduleList[i];
                            this.Refresh();
                            break;
                        }
                    }
                }
            }
            this.Focus();
        }

        private void contextMenuModulWorkingPanel_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
            if (e.ClickedItem == menuModuleImportImage)
            {
                formInstance.ImportImage();
            }
        }

        private void ModulWorkingPanel_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.Button == System.Windows.Forms.MouseButtons.Middle)
            {
                xImage += e.X - lastMouseX;
                yImage += e.Y - lastMouseY;
                this.Refresh();
            }
            else if (e.Button == System.Windows.Forms.MouseButtons.Left)
            {
                if (mouseState == MouseModuleState.Drag)
                {
                    moduleOriginalX += (e.X - lastMouseX) / zoom;
                    moduleOriginalY += (e.Y - lastMouseY) / zoom;
                    activeModule.x = (int)moduleOriginalX;
                    activeModule.y = (int)moduleOriginalY;
                    this.Refresh();
                    formInstance.UpdateActiveModule();
                }
                else if (mouseState == MouseModuleState.ResizeBottom)
                {
                    moduleOriginalY += (e.Y - lastMouseY) / zoom;
                    activeModule.height = Math.Max((int)moduleOriginalY, 1);
                    this.Refresh();
                    formInstance.UpdateActiveModule();
                }
                else if (mouseState == MouseModuleState.ResizeLeft)
                {
                    moduleOriginalX += (e.X - lastMouseX) / zoom;
                    int newWidth = Math.Max(1, (activeModule.x + activeModule.width) - (int)moduleOriginalX);
                    activeModule.x -= newWidth - activeModule.width;
                    activeModule.width = newWidth;
                    this.Refresh();
                    formInstance.UpdateActiveModule();
                }
                else if (mouseState == MouseModuleState.ResizeLeftBottom)
                {
                    moduleOriginalX += (e.X - lastMouseX) / zoom;
                    moduleOriginalY += (e.Y - lastMouseY) / zoom;
                    activeModule.height = Math.Max((int)moduleOriginalY, 1);
                    int newWidth = Math.Max(1, (activeModule.x + activeModule.width) - (int)moduleOriginalX);
                    activeModule.x -= newWidth - activeModule.width;
                    activeModule.width = newWidth;
                    this.Refresh();
                    formInstance.UpdateActiveModule();
                }
                else if (mouseState == MouseModuleState.ResizeLeftTop)
                {
                    moduleOriginalX += (e.X - lastMouseX) / zoom;
                    moduleOriginalY += (e.Y - lastMouseY) / zoom;
                    int newHeight = Math.Max(1, (activeModule.y + activeModule.height) - (int)moduleOriginalY);
                    activeModule.y -= newHeight - activeModule.height;
                    activeModule.height = newHeight;
                    int newWidth = Math.Max(1, (activeModule.x + activeModule.width) - (int)moduleOriginalX);
                    activeModule.x -= newWidth - activeModule.width;
                    activeModule.width = newWidth;
                    this.Refresh();
                    formInstance.UpdateActiveModule();
                }
                else if (mouseState == MouseModuleState.ResizeRight)
                {
                    moduleOriginalX += (e.X - lastMouseX) / zoom;
                    activeModule.width = Math.Max((int)moduleOriginalX, 1);
                    this.Refresh();
                    formInstance.UpdateActiveModule();
                }
                else if (mouseState == MouseModuleState.ResizeRightBottom)
                {
                    moduleOriginalX += (e.X - lastMouseX) / zoom;
                    moduleOriginalY += (e.Y - lastMouseY) / zoom;
                    activeModule.width = Math.Max((int)moduleOriginalX, 1);
                    activeModule.height = Math.Max((int)moduleOriginalY, 1);
                    this.Refresh();
                    formInstance.UpdateActiveModule();
                }
                else if (mouseState == MouseModuleState.ResizeRightTop)
                {
                    moduleOriginalX += (e.X - lastMouseX) / zoom;
                    moduleOriginalY += (e.Y - lastMouseY) / zoom;
                    activeModule.width = Math.Max((int)moduleOriginalX, 1);
                    int newHeight = Math.Max(1, (activeModule.y + activeModule.height) - (int)moduleOriginalY);
                    activeModule.y -= newHeight - activeModule.height;
                    activeModule.height = newHeight;
                    this.Refresh();
                    formInstance.UpdateActiveModule();
                }
                else if (mouseState == MouseModuleState.ResizeTop)
                {
                    moduleOriginalY += (e.Y - lastMouseY) / zoom;
                    int newHeight = Math.Max(1, (activeModule.y + activeModule.height) - (int)moduleOriginalY);
                    activeModule.y -= newHeight - activeModule.height;
                    activeModule.height = newHeight;
                    this.Refresh();
                    formInstance.UpdateActiveModule();
                }
            }
            else if (e.Button == System.Windows.Forms.MouseButtons.None)
            {
                if (activeModule != null)
                {
                    int x = (int)((e.X - xImage) / zoom);
                    int y = (int)((e.Y - yImage) / zoom);

                    if (Util.PointInRect(x, y, activeModule.x - delta, activeModule.y - delta, activeModule.width + delta, activeModule.height + delta))
                    {
                        if (x <= activeModule.x + delta && y <= activeModule.y + delta)
                        {
                            this.Cursor = Cursors.SizeNWSE;
                        }
                        else if (x <= activeModule.x + delta && y >= activeModule.y + activeModule.height - delta)
                        {
                            this.Cursor = Cursors.SizeNESW;
                        }
                        else if (x >= activeModule.x + activeModule.width - delta && y <= activeModule.y + delta)
                        {
                            this.Cursor = Cursors.SizeNESW;
                        }
                        else if (x >= activeModule.x + activeModule.width - delta && y >= activeModule.y + activeModule.height - delta)
                        {
                            this.Cursor = Cursors.SizeNWSE;
                        }
                        else if (x <= activeModule.x + delta)
                        {
                            this.Cursor = Cursors.SizeWE;
                        }
                        else if (x >= activeModule.x + activeModule.width - delta)
                        {
                            this.Cursor = Cursors.SizeWE;
                        }
                        else if (y <= activeModule.y + delta)
                        {
                            this.Cursor = Cursors.SizeNS;
                        }
                        else if (y >= activeModule.y + activeModule.height - delta)
                        {
                            this.Cursor = Cursors.SizeNS;
                        }
                        else
                        {
                            this.Cursor = Cursors.Hand;
                        }
                    }
                    else if(this.Cursor != Cursors.Default)
                    {
                        this.Cursor = Cursors.Default;
                    }
                }
            }
            lastMouseX = e.X;
            lastMouseY = e.Y;
        }

        private void ModulWorkingPanel_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == System.Windows.Forms.MouseButtons.Middle)
            {
                
            }
            else if (e.Button == System.Windows.Forms.MouseButtons.Left)
            {
                if (activeModule != null)
                {
                    int x = (int)((e.X - xImage) / zoom);
                    int y = (int)((e.Y - yImage) / zoom);

                    if (Util.PointInRect(x, y, activeModule.x - delta, activeModule.y - delta, activeModule.width + delta, activeModule.height + delta))
                    {
                        if (x <= activeModule.x + delta && y <= activeModule.y + delta)
                        {
                            mouseState = MouseModuleState.ResizeLeftTop;
                            this.Cursor = Cursors.SizeNWSE;
                            moduleOriginalX = activeModule.x;
                            moduleOriginalY = activeModule.y;
                        }
                        else if (x <= activeModule.x + delta && y >= activeModule.y + activeModule.height - delta)
                        {
                            mouseState = MouseModuleState.ResizeLeftBottom;
                            this.Cursor = Cursors.SizeNESW;
                            moduleOriginalX = activeModule.x;
                            moduleOriginalY = activeModule.height;
                        }
                        else if (x >= activeModule.x + activeModule.width - delta && y <= activeModule.y + delta)
                        {
                            mouseState = MouseModuleState.ResizeRightTop;
                            this.Cursor = Cursors.SizeNESW;
                            moduleOriginalX = activeModule.width;
                            moduleOriginalY = activeModule.y;
                        }
                        else if (x >= activeModule.x + activeModule.width - delta && y >= activeModule.y + activeModule.height - delta)
                        {
                            mouseState = MouseModuleState.ResizeRightBottom;
                            this.Cursor = Cursors.SizeNWSE;
                            moduleOriginalX = activeModule.width;
                            moduleOriginalY = activeModule.height;
                        }
                        else if (x <= activeModule.x + delta)
                        {
                            mouseState = MouseModuleState.ResizeLeft;
                            this.Cursor = Cursors.SizeWE;
                            moduleOriginalX = activeModule.x;
                        }
                        else if (x >= activeModule.x + activeModule.width - delta)
                        {
                            mouseState = MouseModuleState.ResizeRight;
                            this.Cursor = Cursors.SizeWE;
                            moduleOriginalX = activeModule.width;
                        }
                        else if (y <= activeModule.y + delta)
                        {
                            mouseState = MouseModuleState.ResizeTop;
                            this.Cursor = Cursors.SizeNS;
                            moduleOriginalY = activeModule.y;
                        }
                        else if (y >= activeModule.y + activeModule.height - delta)
                        {
                            mouseState = MouseModuleState.ResizeBottom;
                            this.Cursor = Cursors.SizeNS;
                            moduleOriginalY = activeModule.height;
                        }
                        else
                        {
                            mouseState = MouseModuleState.Drag;
                            this.Cursor = Cursors.Hand;
                            moduleOriginalX = activeModule.x;
                            moduleOriginalY = activeModule.y;
                        }
                    }
                }
            }
            lastMouseX = e.X;
            lastMouseY = e.Y;
        }

        public void SetActiveModule(Module module)
        {
            activeModule = module;
            this.Refresh();
        }
        public Module GetActiveModule()
        {
            return activeModule;
        }
        private void ModulWorkingPanel_MouseUp(object sender, MouseEventArgs e)
        {
            mouseState = MouseModuleState.None;
            this.Cursor = Cursors.Default;
        }
    }
}
